// $Id: loggerfailurereason.cpp 65 2004-10-27 21:44:50Z hansemil $
#include "loggerfailurereason.h"
#include "loghandler.h"
#include "node.h"
#include "noderequestfileparameters.h"
#include <iostream>
#include <list>
#include <vector>
#include <string.h>
using namespace std;

/**
 * Init members and register apropriate listeners at the log handler.
 */
LoggerFailureReason::LoggerFailureReason()
{
	LogHandler::getInstance()->addLogger(this, "clock_tick");
	LogHandler::getInstance()->addLogger(this, "node_routeFile");
	resetAll();
}

/**
 * Opens file for writing and stores the Eos pointer
 */
void LoggerFailureReason::eos_simulate_start(void *eos)
{
	openFile(&m_fout, "failurereason.csv");
	m_fout << "Time Step, Request Failed HTL exeeded, Request Failed seen before, Request Failed out of routes, Request Failed busy, Request Succeeded HTL exeeded, Request Succeeded seen before, Request Succeeded out of routes, Request Succeeded busy" << endl;

	m_eos = (Eos *)eos;
}

/**
 * Closes file
 */
void LoggerFailureReason::eos_simulate_stop(void *eos)
{
	m_fout.close();
}

/**
 * Writes the statistics for each tick
 */
void LoggerFailureReason::clock_tick(unsigned int time)
{
	// Write time step
	m_fout << time;

	// Write statistics
	int *tempArray[2] = {m_requestFailedReason, m_requestSuccededReason};
	int tempCount[2] = {m_requestFailedCount, m_requestSuccededCount};
	for(int i=0;i<2;i++){
		for(int j=0;j<4;j++){
			m_fout << ",";
			if(tempCount[i]){
				m_fout << tempArray[i][j]/tempCount[i];
			}
			else{
				m_fout << "0";
			}
		}
	}

	// Write end
	m_fout << endl;

	// Clear variables for next timestep
	resetAll();
}

/**
 * Checks if a request call is a failed and saves why for writing on tick
 */
void LoggerFailureReason::node_routeFile(void *thisNode, void *requestor, void *params_in, unsigned char result)
{
	NodeRequestFileParameters *params = (NodeRequestFileParameters *)params_in;
	// Check that it's not a insert
	if(!params->m_insert){
		// Check if the request failed
		if(result){
			m_requestUnknownReason[result-1]++;
		}

		// Final success
		if(!result && thisNode==params->m_fileOwner){
			m_requestSuccededCount++;
			saveRequest(m_requestSuccededReason);
		}
		// Final fail
		else if(result && thisNode == requestor){
			m_requestFailedCount++;
			saveRequest(m_requestFailedReason);
		}
	}
}

/**
 * Resets all member variables
 */
void LoggerFailureReason::resetAll()
{
	m_requestFailedCount = 0;
	m_requestSuccededCount = 0;
	bzero(m_requestFailedReason,sizeof(int)*4);
	bzero(m_requestSuccededReason,sizeof(int)*4);
}

/**
 * Copies the temporary result array to a final one
 * @param targetArray The final array to copy data to
 */
void LoggerFailureReason::saveRequest(int *targetArray)
{
	memcpy(targetArray, m_requestUnknownReason, sizeof(int)*4);
	bzero(m_requestUnknownReason,sizeof(int)*4);
}
